package com.kj.tms.system.service.role.serviceImpl;


import com.kj.tms.common.bean.dao.BaseMapper;
import com.kj.tms.common.bean.dto.Pager;
import com.kj.tms.common.bean.dto.ReturnData;
import com.kj.tms.common.bean.redis.RedisAccess;
import com.kj.tms.common.bean.service.BaseService;
import com.kj.tms.common.bean.session.SessionManager;
import com.kj.tms.common.utils.StringUtil;
import com.kj.tms.common.utils.constant.Consts;
import com.kj.tms.common.utils.uuid.IdGen;
import com.kj.tms.pri.system.menu.dto.ModuleDto;
import com.kj.tms.pri.system.menu.service.ModuleService;
import com.kj.tms.pri.system.role.dto.RoleDto;
import com.kj.tms.pri.system.role.dto.RoleMenuDto;
import com.kj.tms.pri.system.role.service.RoleMenuService;
import com.kj.tms.pri.system.role.service.RoleService;
import com.kj.tms.pri.system.user.dto.UserDto;
import com.kj.tms.pri.system.user.dto.UserOrgRoleDto;
import com.kj.tms.pri.system.user.service.UserOrgRoleService;
import com.kj.tms.system.service.role.dao.RoleMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by wzl on 2017/10/17.
 */
@Service
public class RoleServiceImpl extends BaseService<RoleDto> implements RoleService {

    private Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private SessionManager sessionManager;
    @Autowired
    private UserOrgRoleService userOrgRoleServiceImpl;
    @Autowired
    private RedisAccess redisAccessImpl;
    @Autowired
    private ModuleService moduleServiceImpl;
    @Autowired
    private RoleMenuService roleMenuServiceImpl;

    @Override
    public Pager queryByPage(@RequestBody RoleDto dto) {
        return super.selectPage(dto);
    }

    @Override
    public BaseMapper<RoleDto> getMapper() {
        return roleMapper;
    }

    /**
     * @Method
     * @Param
     * @Return
     * @Exception
     * @Description [redis中取得初始的角色信息， 然后分页信息]
     * @Author ZHANGSONG
     * @Version 1.0
     * @Date 2017/11/16 10:40
     */

    @Override
    public Map<String, Object> listByPage(@RequestBody RoleDto model) {
        Map<String, Object> returnObject = new HashMap<>();
          model.setDelMark(Consts.DEL_MARK_0);
//
        Pager pager = super.selectPage(model);
        List<RoleDto> roleList =pager.getResults();

        for (RoleDto roleDto : roleList) {
            List<RoleDto> mutexList = new ArrayList<>();
            String mutex = roleDto.getMutex();
            if(!StringUtil.isEmptyOrNull(mutex)){
                String[]  mutexStrs=mutex.split("，");
                for(int j=0,len=mutexStrs.length;j<len;j++){
                    String roleIdMutex =   mutexStrs[j];
                    RoleDto roleDtoMutes = new RoleDto();
                    roleDtoMutes.setRoleId(roleIdMutex);
                    RoleDto roleMutes =   roleMapper.getById(roleDtoMutes);
                    mutexList.add(roleMutes);
                }
            }
            roleDto.setMutexList(mutexList);
        }
        returnObject.put("total", pager.getRowCount());
        returnObject.put("rows", roleList);
//        }
        //设置页面数据
        return returnObject;
    }

    /**
     * @Method
     * @Param
     * @Return
     * @Exception
     * @Description [通过前端传值是否有id判断增加和修改 ，  并且校验是否存在角色code]
     * @Author zhangsong
     * @Version 1.0
     * @Date 2017/11/16 10:39
     */

    @Override
    public ReturnData save(@RequestBody RoleDto dto) {
        UserDto user = (UserDto) sessionManager.getAttribute("user");
        if (dto.getRoleId() == null) {
            //查询角色是否已经存在
            RoleDto dto_exist = getByCode(dto.getRoleCode());
            if (dto_exist != null) {
                return new ReturnData(Consts.ERROR, "角色代码已经存在~", null);
            }
            dto.setValidMark(Consts.VALID_MARK_1);
            dto.setDelMark(Consts.DEL_MARK_0);
            //请求的角色数据dto保存
            dto.setRoleId(IdGen.getId());
            dto.setCreateUser(user.getUserId());
            dto.setCreateTime(new Timestamp(System.currentTimeMillis()));
            add(dto);
        } else {
            RoleDto model = new RoleDto();
            //修改用户信息
            model.setRoleCode(dto.getRoleCode());
            //查询要修改的信息 code  是否已存在
            RoleDto roleDto = getByCode(model.getRoleCode());
            if (null != roleDto && !(roleDto.getRoleId().equals(dto.getRoleId()))) {
                return new ReturnData(Consts.ERROR, "角色代码已经存在~", null);
            }
            updateBySelective(dto);
        }
        return new ReturnData(Consts.SUCCESS, "", null);
    }

    /**
     * 根据用户登录机构查询角色
     *
     * @param map 查询条件
     * @return List<RoleDto> 角色列表
     */
    @Override
    public List<RoleDto> listByUserOrg(@RequestBody Map map) {
        return roleMapper.listByUserOrg(map);
    }

    /**
     * @Method
     * @Param
     * @Return
     * @Exception
     * @Description [初始化角色信息]
     * @Author ZHANGSONG
     * @Version 1.0
     * @Date 2017/11/16 10:41
     */

    @Override
    public List<RoleDto> listAll() {
        return roleMapper.listAll();
    }

    /**
     * @Method
     * @Param       roleId 角色ID
     * @Return
     * @Exception
     * @Description [初始化角色显示未删除有效信息]
     * @Author      zhangsong
     * @Version     1.0
     * @Date        2017/11/16 10:26
     */
    @Override
    public List<RoleDto> list(@RequestParam(value = "roleId", required = false) String roleId) {
        Map<String , Object> map = new HashMap<>();
        map.put("roleId",roleId);
        return roleMapper.list(map);
    }

    @Override
    public ReturnData delete(@RequestParam("roleId") String roleId) {
        //根据角色查关联表数据是够存在。
        List<UserOrgRoleDto> userOrgRoleDtoList = listByRoleId(roleId);
        if (userOrgRoleDtoList.size() == 0) {
            //查询菜单关联信息
            List<ModuleDto> datalist_yfp = moduleServiceImpl.queryMenuByRoleId(roleId);
            if (datalist_yfp.size() == 0) {
                //进行物理删除 role数据 关联id
                deleteByRoleId(roleId);
            } else {
                return new ReturnData(Consts.ERROR, "该角色已分配权限，禁止删除。", null);
            }
        } else {
            return new ReturnData(Consts.ERROR, "该角色有用户正在使用，禁止删除。", null);
        }
        return new ReturnData(Consts.SUCCESS, "", null);
    }

    /**
     * @Method
     * @Param
     * @Return
     * @Exception
     * @Description [角色权限树形， 角色已有权限显示出， 之后更新的新的权限（删除全部的关联权限，在 批量新增）]
     * @Author zhangsong
     * @Version 1.0
     * @Date 2017/11/16 10:41
     */
    @Override
    public ReturnData listAddMenu(@RequestBody RoleDto model, @RequestParam("menuCodes") String menuCodes) {
        List<RoleMenuDto> list = new ArrayList<>();
        RoleMenuDto roleMenu = new RoleMenuDto();
        roleMenu.setRoleId(model.getRoleId());
        //根据页面勾选， 先根据Id删除所有已选择的，从新插入页面勾选的菜单Id
        roleMenuServiceImpl.delete(roleMenu);
        if (StringUtil.isNotNull(menuCodes)) {
            String[] mCodes = menuCodes.split(",");
            for (int i = 0; i < mCodes.length; i++) {
                RoleMenuDto roleMenuDto = new RoleMenuDto();
                roleMenuDto.setRoleId(model.getRoleId());
                roleMenuDto.setMenuCode(mCodes[i]);
                list.add(roleMenuDto);
            }
            roleMenuServiceImpl.batchAdd(list);
        }
        return new ReturnData(Consts.SUCCESS, "角色权限分配成功~", null);
    }

    /**
     * 根据字段查询 角色信息
     *
     * @param roleCode
     * @return
     */

    @Override
    public RoleDto getByCode(@RequestParam("roleCode")String roleCode) {
        RoleDto role = roleMapper.getByCode(roleCode);
        return role;
    }

    /**
     * 更新插入 信息
     *
     * @param roleDto
     */

    @Override
    public void add(@RequestBody RoleDto roleDto) {
        roleMapper.add(roleDto);
        updateRedisData(roleDto,"save");
    }

    /**
     * 更新角色信息
     *
     * @param roleDto
     */
    @Override
    public void updateBySelective(@RequestBody RoleDto roleDto) {
        roleMapper.update(roleDto);
        updateRedisData(roleDto,"update");
    }

    /**
     * 删除角色， 进行物理删除
     *
     * @param roleId
     */
    @Override
    public void deleteByRoleId(@RequestParam("roleId") String roleId) {
        roleMapper.deleteByRoleId(roleId);
        deleteRedisData(roleId);
    }

    /**
     * 查询角色的关联信息UserOrgRoleDto
     *
     * @param roleId
     * @return
     */
    @Override
    public List<UserOrgRoleDto> listByRoleId(@RequestParam("roleId") String roleId) {
        return userOrgRoleServiceImpl.listByRoleId(roleId);
    }

    /**
     * 删除角色的关联信息
     *
     * @param userId
     * @param curOrgCode
     */
    @Override
    public void deleteUserRole(@RequestParam("userId") String userId, @RequestParam("orgCode") String curOrgCode) {
        roleMapper.deleteUserRole(userId, curOrgCode);
    }

    /**
     * @Method
     * @Param
     * @Return
     * @Exception
     * @Description [批量新增角色信息 ]
     * @Author zhangsong
     * @Version 1.0
     * @Date 2017/11/16 10:45
     */

    @Override
    public void batchAddUserRole(@RequestBody List<Object> dtos) {
        roleMapper.batchAddUserRole(dtos);
    }

    /**

     * @method [updateRedisData]
     * @description [保存、修改或者禁用启用之后，更新redis]
     * @author 王国庆
     * @param dto
     * @param type
     * @return void
     * @version 1.0
     * @date 2017年11月09日 10:04
     */
    private void updateRedisData(RoleDto dto ,String type) {
        List<RoleDto> roleList = redisAccessImpl.lrandge(Consts.ROLE, 0, -1);
        if(!StringUtil.isEmptyOrNull(roleList)) { //不考虑开始初始化没有值得情况
            logger.info("保存、修改或者禁用启用之后，更新redis 放入角色列表------role size: " + roleList.size());
            if("save".equals(type)){
                 redisAccessImpl.lpush(Consts.ROLE, -1, dto);
            }else{
                for (int k = 0; k < roleList.size(); k++) {
                    if (dto.getRoleId().equals(roleList.get(k).getRoleId())) {
                        dto = roleMapper.getById(dto.getRoleId());
                        redisAccessImpl.lset(Consts.ROLE, k, dto);
                        break;
                    }
                }
            }

        }
    }

    /**
     * @return void
     * @method [deleteRedisData]
     * @description [删除之后，更新redis]
     * @author 王国庆
     * @version 1.0
     * @date 2017年11月09日 10:04
     */
    private void deleteRedisData(String roleId) {
        List<RoleDto> roleList = redisAccessImpl.lrandge(Consts.ROLE, 0, -1);
        if(!StringUtil.isEmptyOrNull(roleList)) { //不考虑开始初始化没有值得情况
            for (int k = 0; k < roleList.size(); k++) {
                if (roleId.equals(roleList.get(k).getRoleId())) {
                    redisAccessImpl.lremove(Consts.ROLE, k, roleList.get(k));
                    break;
                }
            }
        }
    }

    /**
     * @method      [queryMutexByList]
     * @description [根据角色名称查询互斥角色]
     * @author      王国庆
     * @version     1.0
     * @param       roleName
     * @exception
     * @date        2018年01月08日 16:50
     */
    public List <RoleDto> queryMutexByList(@RequestParam("roleName") String roleName){
      return   roleMapper.queryMutexByList(roleName);
    }


    /**
     * @method      [queryMutexNameByList]
     * @description [根据角色ID查询角色信息]
     * @author      王国庆
     * @version     1.0
     * @param       roleId 角色ID
     * @exception
     * @date        2018年01月08日 16:50
     */
    public RoleDto queryMutexNameByList(@RequestParam("roleId") String roleId){
        return roleMapper.queryMutexNameByList(roleId);
    }
}
